package controllers;

import data.posts.PostDataGateway;
import data.users.UserDataGateway;
import models.domain.LinkPost;
import models.domain.QuotePost;
import models.domain.RegularPost;
import models.general.AbstractRumblrPost;
import models.general.UserDTO;
import models.service.PostService;
import models.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import play.data.validation.Validation;
import play.mvc.Controller;
import play.mvc.Scope;

import java.util.ArrayList;
import java.util.List;

public class Application extends Controller
{

    /**
     *  Index (login window). Is rendered when a user hasn't logged in for the session, otherwise dashboard() is called
     */
    public static void index() {

        if (session.get("user") == null)
            render();
        dashboard(session.get("user"));

    }

    /**
     * login function: receives it's parameters from the login form index.html
     * calls dashboard() on a successful login.
     * @param username
     * @param password
     */
    public static void login(String username, String password)
    {
        ApplicationContext ctx = new FileSystemXmlApplicationContext("HONN_Verkefni5/applicationContext.xml");
        UserService userService = (UserService) ctx.getBean("userService");
        UserDataGateway userDataGateway = (UserDataGateway) ctx.getBean("userDataGateway");

        userService.setUserDataGateway(userDataGateway);

        Validation.required("username", username);
        Validation.required("password", password);

        if (Validation.hasErrors())
        {
            params.flash();
            Validation.keep();
            index();
        }
        UserDTO user = null;
        user = userService.login(username, password);

        if (user == null)
        {
            Validation.addError("error", "Username or password is incorrect.");

            Validation.keep();
            index();
        }
        Scope.Session.current().put("user", user.getUsername());
        dashboard(user.getUsername());

    }


    /**
     * dashboard is called by login() and index() on a successful login attempt or if the user is already
     * in the session. Receives username to determine whose dashboard to render, and renders the dashboard.html view
     * with a populated list of posts.
     * @param username
     */
    public static void dashboard(String username)
    {
        ApplicationContext ctx = new FileSystemXmlApplicationContext("HONN_Verkefni5/applicationContext.xml");

        PostService postService = (PostService) ctx.getBean("postService");
        PostDataGateway postDataGateway = (PostDataGateway) ctx.getBean("postDataGateway");

        postService.setPostDataGateway(postDataGateway);

        List<AbstractRumblrPost> postList = new ArrayList<AbstractRumblrPost>();

        postList = (List)postService.getPosts(session.get("user"));

        render(postList);
    }

    /**
     * The create function is used by the regular.html, link.html and quote.html views
     * Parameters are received through their respective forms and are used to find out what
     * kind of post should be passed on down to the domain layer.
     * @param type
     * @param firstInput
     * @param secondInput
     */
    public static void create(String type, String firstInput, String secondInput)
    {
        Validation.required("firstInput", firstInput).message("");
        Validation.required("secondInput", secondInput).message("Please fill in this field");

        ApplicationContext ctx = new FileSystemXmlApplicationContext("HONN_Verkefni5/applicationContext.xml");
        PostService postService = (PostService) ctx.getBean("postService");
        PostDataGateway postDataGateway = (PostDataGateway) ctx.getBean("postDataGateway");

        postService.setPostDataGateway(postDataGateway);

        if (type.equals("link"))
            postService.addPost(new LinkPost(firstInput, secondInput), session.get("user"));
        else if (type.equals("quote"))
            postService.addPost(new QuotePost(firstInput, secondInput), session.get("user"));
        else if (type.equals("regular"))
            postService.addPost(new RegularPost(firstInput, secondInput), session.get("user"));
        dashboard(session.get("user"));


    }

    /**
     * The id of the post being liked is passed in as a parameter and a like is eventually added into the ru_post_details
     * table
     * @param postId
     */
    public static void addLike(int postId)
    {
        ApplicationContext ctx = new FileSystemXmlApplicationContext("HONN_Verkefni5/applicationContext.xml");
        PostService postService = (PostService) ctx.getBean("postService");
        PostDataGateway postDataGateway = (PostDataGateway) ctx.getBean("postDataGateway");

        postService.setPostDataGateway(postDataGateway);

        postService.addLike(postId, session.get("user"));

    }

    /**
     * A post's id is passed in as a parameter in order to retrieve the number of likes belonging to said post
     * @param postId
     */
    public static void getLikes(int postId)
    {
        ApplicationContext ctx = new FileSystemXmlApplicationContext("HONN_Verkefni5/applicationContext.xml");
        PostService postService = (PostService) ctx.getBean("postService");
        PostDataGateway postDataGateway = (PostDataGateway) ctx.getBean("postDataGateway");

        postService.setPostDataGateway(postDataGateway);

        int nLikes = postService.getLikes(postId);
        renderJSON(nLikes);
    }


    //Render functions for their respective views.
    public static void link()
    {
        render();
    }

    public static void regular()
    {
        render();
    }

    public static void quote()
    {
        render();
    }
}